<template>
  <Teleport :to="teleportTarget" :disabled="!teleportTarget">
    <div
      class="square-loader-container"
      v-if="loading"
      :style="containerStyles"
    >
      <div class="square-loader" :style="loaderStyles">
        <div class="square-box" :style="boxStyles"></div>
        <div class="square-shadow" :style="shadowStyles"></div>
      </div>
    </div>
  </Teleport>
</template>


<script setup>
import { computed } from 'vue';

const props = defineProps({
  loading: {
    type: Boolean,
    default: true
  },
  size: {
    type: Number,
    default: 50
  },
  color: {
    type: String,
    default: '#0ba5d3'
  },
  shadowColor: {
    type: String,
    default: '#c4f2ff'
  },
  speed: {
    type: Number,
    default: 0.5
  },
  zIndex: {
    type: Number,
    default: 11
  },
  teleportTo: {
    type: [String, Boolean],
    default: false,
    validator: (value) => {
      return typeof value === 'boolean' ||
            (typeof value === 'string' && value.startsWith('#'))
    }
  },
  fullscreen: {
    type: Boolean,
    default: false
  },
  backgroundColor: {
    type: String,
    default: 'transparent'
  }
});
// 计算传送目标
const teleportTarget = computed(() => {
  if (props.fullscreen) return 'body' // 全屏模式强制传送到 body
  if (props.teleportTo === true) return 'body'
  if (typeof props.teleportTo === 'string') return props.teleportTo
  return null // 禁用传送
})
// 修改后的容器样式（需要适应不同定位方式）
const containerStyles = computed(() => ({
  position: props.fullscreen ? 'fixed' : 'absolute',
  top: 0,
  left: 0,
  right: 0,
  bottom: props.fullscreen ? 0 : 'unset',
  display: 'flex',
  justifyContent: 'center',
  alignItems: 'center',
  background: props.backgroundColor,
  backdropFilter: 'blur(2px)',
  zIndex: props.zIndex,
  // 当传送到 body 时需要 fixed 定位
  ...(teleportTarget.value === 'body' && {
    position: 'fixed',
  })
}));

const loaderStyles = computed(() => ({
  position: 'relative',
  width: `${props.size}px`,
  height: `${props.size + 20}px`
}));

const boxStyles = computed(() => ({
  width: `${props.size}px`,
  height: `${props.size}px`,
  background: props.color,
  animationDuration: `${props.speed}s`
}));

const shadowStyles = computed(() => ({
  width: `${props.size}px`,
  height: `${Math.max(5, props.size * 0.1)}px`,
  background: props.shadowColor,
  top: `${props.size + 13}px`, // 动态定位关键修改
  animationDuration: `${props.speed}s`
}));
</script>

<style scoped>
.square-loader-container {
  width: 100%;
  height: 100%;
}

.square-loader {
  display: flex;
  justify-content: center;
  align-items: center;
}

.square-box {
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 3px;
  animation-name: box-animate;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

.square-shadow {
  position: absolute;
  left: 0;
  border-radius: 50%;
  opacity: 1;
  animation-name: shadow-animate;
  animation-timing-function: linear;
  animation-iteration-count: infinite;

}

@keyframes box-animate {
  17% {
    border-bottom-right-radius: 3px;
  }
  25% {
    transform: translateY(9px) rotate(22.5deg);
  }
  50% {
    transform: translateY(18px) scale(1, 0.9) rotate(45deg);
    border-bottom-right-radius: 40px;
  }
  75% {
    transform: translateY(9px) rotate(67.5deg);
  }
  100% {
    transform: translateY(0) rotate(90deg);
  }
}

@keyframes shadow-animate {
  50% {
    transform: scale(1.2, 1);
  }
}
</style>
